package org.example.compare.schedule;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.example.compare.dto.*;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 测试数据生成器类，用于为calculateItem_5函数生成测试数据
 * 该函数使用到的非函数参数列表外部变量包括:
 * 1. SchData.hParamSet - 系统参数集，需要获取"MinInLibSTDPer"参数
 * 2. SchData.orderId2Order - 订单映射，用于获取工序对应的订单
 * 3. SchData.hOrderProcessDependency - 工序依赖关系
 * 4. hProcessSet - 需要进行排产的工序集
 * 5. sPositionsScore - 可以排产的工位
 * 6. hScoreByProcess - 按工序查找的分数表
 * 7. preScheduling - 预排产服务，用于查找后置工序和判断工序类型
 */
public class CalculateItem5TestDataGenerator {

    private static final ObjectMapper objectMapper = new ObjectMapper();
    private static final Random random = new Random();

    static {
        objectMapper.registerModule(new JavaTimeModule());
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
    }

    /**
     * 生成随机测试数据并保存到文件
     */
    public static void generateRandomTestData(int iteration) throws IOException {
        String basePath = "../../test_data/calculateItem_5/random_case_" + iteration;
        File baseDir = new File(basePath);

        // 清空文件夹
        clearDirectory(baseDir);

        if (!baseDir.exists()) {
            baseDir.mkdirs();
        }

        // 生成测试数据
        generateSysParamData(basePath);
        Map<String, OrderDto> orderId2Order = generateOrderData(basePath);
        Map<Long, OrderProcess> hProcessSet = generateProcessSetData(basePath, orderId2Order, new HashMap<>());
        Map<Long, Set<Long>> hOrderProcessDependency = generateProcessDependencyData(basePath, hProcessSet);
        Set<Long> sPositionsScore = generatePositionScoreData(basePath);
        generateScoreByProcessData(basePath, hProcessSet, sPositionsScore);
        generateFunctionParams(basePath);

        // 更新orderId2Order，确保订单数据是最新的
        objectMapper.writeValue(new File(basePath + "/orderId2Order.json"), orderId2Order);
    }

    /**
     * 生成手动测试数据并保存到文件
     */
    public static void generateManualTestData(int caseNumber) throws IOException {
        String basePath = "../../test_data/calculateItem_5/manual_case_" + caseNumber;
        File baseDir = new File(basePath);

        // 清空文件夹
        clearDirectory(baseDir);

        if (!baseDir.exists()) {
            baseDir.mkdirs();
        }

        if (caseNumber == 1) {
            generateManualTestCase1(basePath);
        } else if (caseNumber == 2) {
            generateManualTestCase2(basePath);
        }
    }

    /**
     * 生成手动测试案例1 - 基本正常情况
     */
    private static void generateManualTestCase1(String basePath) throws IOException {
        // 生成系统参数
        Map<String, SysParam> hParamSet = new HashMap<>();
        SysParam minInLibSTDPer = new SysParam();
        minInLibSTDPer.setParamCode("MinInLibSTDPer");
        minInLibSTDPer.setParamDefaultValue("300");
        hParamSet.put("MinInLibSTDPer", minInLibSTDPer);
        objectMapper.writeValue(new File(basePath + "/hParamSet.json"), hParamSet);

        // 生成订单数据
        Map<String, OrderDto> orderId2Order = new HashMap<>();
        OrderDto order1 = OrderDto.InitOrder();
        order1.setMLocalOrderNum("TEST5001123456");
        order1.setMiTotalPlanCnt(1000);

        // 初始化工序分组
        Map<Integer, OrderProcess> processGroup1 = new TreeMap<>();
        order1.getMOrderProcessSetGroupByPart().put(100L, processGroup1);
        orderId2Order.put("TEST5001123456", order1);
        objectMapper.writeValue(new File(basePath + "/orderId2Order.json"), orderId2Order);

        // 生成工序集数据
        Map<Long, OrderProcess> hProcessSet = new HashMap<>();

        // 工序1 (前置工序)
        OrderProcess process1 = OrderProcess.InitOrderProcess(order1);
        process1.setProcessId(1001L);
        process1.setOrderProcessId(1001L);
        process1.setMfProcessTotalTime(120.0f); // 2分钟标准工时
        process1.setMiFinishedCnt(200);
        process1.setMiPartSeqNum(1);
        process1.setMPartId(100L);

        ProcessSch scheduling1 = new ProcessSch();
        scheduling1.setMbHoldFlag(false);
        scheduling1.setMbNGFlag(false);

        // 设置在产工位
        Set<Long> workingPos1 = new HashSet<>();
        workingPos1.add(30001L);
        scheduling1.setMisWorkingPos(workingPos1);

        // 设置可做工位
        Set<Long> posCanDo1 = new HashSet<>();
        posCanDo1.add(30001L);
        posCanDo1.add(30002L);
        scheduling1.setMPosCanDo(posCanDo1);

        // 设置在库件数
        CBoxSet boxesInLib1 = new CBoxSet();
        boxesInLib1.setMiCutCnt(50);
        boxesInLib1.setMiBoxCnt(5);
        scheduling1.setMBoxesInLib(boxesInLib1);

        process1.setMScheduling(scheduling1);
        hProcessSet.put(1001L, process1);

        // 工序2 (后置工序，依赖工序1)
        OrderProcess process2 = OrderProcess.InitOrderProcess(order1);
        process2.setProcessId(1002L);
        process2.setOrderProcessId(1002L);
        process2.setMfProcessTotalTime(180.0f); // 3分钟标准工时
        process2.setMiFinishedCnt(150);
        process2.setMiPartSeqNum(2);
        process2.setMPartId(100L);

        ProcessSch scheduling2 = new ProcessSch();
        scheduling2.setMbHoldFlag(false);
        scheduling2.setMbNGFlag(false);

        // 设置在产工位
        Set<Long> workingPos2 = new HashSet<>();
        workingPos2.add(30003L);
        scheduling2.setMisWorkingPos(workingPos2);

        // 设置可做工位
        Set<Long> posCanDo2 = new HashSet<>();
        posCanDo2.add(30003L);
        posCanDo2.add(30004L);
        scheduling2.setMPosCanDo(posCanDo2);

        // 设置在库件数
        CBoxSet boxesInLib2 = new CBoxSet();
        boxesInLib2.setMiCutCnt(30);
        boxesInLib2.setMiBoxCnt(3);
        scheduling2.setMBoxesInLib(boxesInLib2);

        process2.setMScheduling(scheduling2);
        hProcessSet.put(1002L, process2);

        // 保存到文件
        objectMapper.writeValue(new File(basePath + "/hProcessSet.json"), hProcessSet);

        // 生成工序依赖关系
        Map<Long, Set<Long>> hOrderProcessDependency = new HashMap<>();
        Set<Long> dependency1 = new HashSet<>();
        dependency1.add(1001L); // 工序2依赖工序1
        hOrderProcessDependency.put(1002L, dependency1);
        objectMapper.writeValue(new File(basePath + "/hOrderProcessDependency.json"), hOrderProcessDependency);

        // 生成可以排产的工位数据
        Set<Long> sPositionsScore = new HashSet<>();
        sPositionsScore.add(30001L);
        sPositionsScore.add(30002L);
        sPositionsScore.add(30003L);
        sPositionsScore.add(30004L);

        // 保存到文件
        objectMapper.writeValue(new File(basePath + "/sPositionsScore.json"), sPositionsScore);

        // 生成按工序查找的分数表数据
        Map<Long, List<Score>> hScoreByProcess = new HashMap<>();

        // 工序1的分数
        List<Score> scores1 = new ArrayList<>();
        Score score1_1 = new Score();
        score1_1.setPositionId(30001L);
        score1_1.setTotal(80.0);
        double[] scoreItems1 = new double[20];
        Arrays.fill(scoreItems1, 5.0);
        score1_1.setScoreItem(scoreItems1);
        scores1.add(score1_1);

        Score score1_2 = new Score();
        score1_2.setPositionId(30002L);
        score1_2.setTotal(75.0);
        double[] scoreItems2 = new double[20];
        Arrays.fill(scoreItems2, 4.5);
        score1_2.setScoreItem(scoreItems2);
        scores1.add(score1_2);

        hScoreByProcess.put(1001L, scores1);

        // 工序2的分数
        List<Score> scores2 = new ArrayList<>();
        Score score2_1 = new Score();
        score2_1.setPositionId(30003L);
        score2_1.setTotal(85.0);
        double[] scoreItems3 = new double[20];
        Arrays.fill(scoreItems3, 6.0);
        score2_1.setScoreItem(scoreItems3);
        scores2.add(score2_1);

        Score score2_2 = new Score();
        score2_2.setPositionId(30004L);
        score2_2.setTotal(70.0);
        double[] scoreItems4 = new double[20];
        Arrays.fill(scoreItems4, 4.0);
        score2_2.setScoreItem(scoreItems4);
        scores2.add(score2_2);

        hScoreByProcess.put(1002L, scores2);

        // 保存到文件
        objectMapper.writeValue(new File(basePath + "/hScoreByProcess.json"), hScoreByProcess);

        // 生成函数参数，ratio值大于0.01
        Map<String, Object> functionParams = new HashMap<>();
        functionParams.put("ratio", 0.1);
        objectMapper.writeValue(new File(basePath + "/testCases.json"), functionParams);

        // 更新订单中的工序分组
        processGroup1.put(1, process1);
        processGroup1.put(2, process2);

        // 更新orderId2Order文件，确保包含完整的工序分组信息
        objectMapper.writeValue(new File(basePath + "/orderId2Order.json"), orderId2Order);
    }

    /**
     * 生成手动测试案例2 - 包含特殊工序类型（挂起、NG等）
     */
    private static void generateManualTestCase2(String basePath) throws IOException {
        // 生成系统参数
        Map<String, SysParam> hParamSet = new HashMap<>();
        SysParam minInLibSTDPer = new SysParam();
        minInLibSTDPer.setParamCode("MinInLibSTDPer");
        minInLibSTDPer.setParamDefaultValue("600");
        hParamSet.put("MinInLibSTDPer", minInLibSTDPer);
        objectMapper.writeValue(new File(basePath + "/hParamSet.json"), hParamSet);

        // 生成订单数据
        Map<String, OrderDto> orderId2Order = new HashMap<>();
        OrderDto order1 = OrderDto.InitOrder();
        order1.setMLocalOrderNum("TEST5002789012");
        order1.setMiTotalPlanCnt(800);

        // 初始化工序分组
        Map<Integer, OrderProcess> processGroup1 = new TreeMap<>();
        order1.getMOrderProcessSetGroupByPart().put(200L, processGroup1);
        orderId2Order.put("TEST5002789012", order1);
        objectMapper.writeValue(new File(basePath + "/orderId2Order.json"), orderId2Order);

        // 生成工序集数据
        Map<Long, OrderProcess> hProcessSet = new HashMap<>();

        // 工序1 (正常状态)
        OrderProcess process1 = OrderProcess.InitOrderProcess(order1);
        process1.setProcessId(2001L);
        process1.setOrderProcessId(2001L);
        process1.setMfProcessTotalTime(90.0f); // 1.5分钟标准工时
        process1.setMiFinishedCnt(100);
        process1.setMiPartSeqNum(1);
        process1.setMPartId(200L);
        process1.setMProcessBrief(""); // 正常工序

        ProcessSch scheduling1 = new ProcessSch();
        scheduling1.setMbHoldFlag(false);
        scheduling1.setMbNGFlag(false);

        // 设置在产工位
        Set<Long> workingPos1 = new HashSet<>();
        workingPos1.add(40001L);
        workingPos1.add(40002L);
        scheduling1.setMisWorkingPos(workingPos1);

        // 设置可做工位
        Set<Long> posCanDo1 = new HashSet<>();
        posCanDo1.add(40001L);
        posCanDo1.add(40002L);
        posCanDo1.add(40003L);
        scheduling1.setMPosCanDo(posCanDo1);

        // 设置在库件数
        CBoxSet boxesInLib1 = new CBoxSet();
        boxesInLib1.setMiCutCnt(100);
        boxesInLib1.setMiBoxCnt(10);
        scheduling1.setMBoxesInLib(boxesInLib1);

        process1.setMScheduling(scheduling1);
        hProcessSet.put(2001L, process1);

        // 工序2 (挂起状态)
        OrderProcess process2 = OrderProcess.InitOrderProcess(order1);
        process2.setProcessId(2002L);
        process2.setOrderProcessId(2002L);
        process2.setMfProcessTotalTime(150.0f); // 2.5分钟标准工时
        process2.setMiFinishedCnt(50);
        process2.setMiPartSeqNum(2);
        process2.setMPartId(200L);
        process2.setMProcessBrief(""); // 正常工序

        ProcessSch scheduling2 = new ProcessSch();
        scheduling2.setMbHoldFlag(true); // 挂起状态
        scheduling2.setMbNGFlag(false);

        // 设置在产工位
        Set<Long> workingPos2 = new HashSet<>();
        workingPos2.add(40004L);
        scheduling2.setMisWorkingPos(workingPos2);

        // 设置可做工位
        Set<Long> posCanDo2 = new HashSet<>();
        posCanDo2.add(40004L);
        scheduling2.setMPosCanDo(posCanDo2);

        // 设置在库件数
        CBoxSet boxesInLib2 = new CBoxSet();
        boxesInLib2.setMiCutCnt(20);
        boxesInLib2.setMiBoxCnt(2);
        scheduling2.setMBoxesInLib(boxesInLib2);

        process2.setMScheduling(scheduling2);
        hProcessSet.put(2002L, process2);

        // 工序3 (NG状态)
        OrderProcess process3 = OrderProcess.InitOrderProcess(order1);
        process3.setProcessId(2003L);
        process3.setOrderProcessId(2003L);
        process3.setMfProcessTotalTime(200.0f); // 约3.3分钟标准工时
        process3.setMiFinishedCnt(75);
        process3.setMiPartSeqNum(3);
        process3.setMPartId(200L);
        process3.setMProcessBrief(""); // 正常工序

        ProcessSch scheduling3 = new ProcessSch();
        scheduling3.setMbHoldFlag(false);
        scheduling3.setMbNGFlag(true); // NG状态

        // 设置在产工位
        Set<Long> workingPos3 = new HashSet<>();
        workingPos3.add(40005L);
        scheduling3.setMisWorkingPos(workingPos3);

        // 设置可做工位
        Set<Long> posCanDo3 = new HashSet<>();
        posCanDo3.add(40005L);
        scheduling3.setMPosCanDo(posCanDo3);

        // 设置在库件数
        CBoxSet boxesInLib3 = new CBoxSet();
        boxesInLib3.setMiCutCnt(40);
        boxesInLib3.setMiBoxCnt(4);
        scheduling3.setMBoxesInLib(boxesInLib3);

        process3.setMScheduling(scheduling3);
        hProcessSet.put(2003L, process3);

        // 工序4 (特殊类型 - 外线工序)
        OrderProcess process4 = OrderProcess.InitOrderProcess(order1);
        process4.setProcessId(2004L);
        process4.setOrderProcessId(2004L);
        process4.setMfProcessTotalTime(120.0f);
        process4.setMiFinishedCnt(60);
        process4.setMiPartSeqNum(4);
        process4.setMPartId(200L);
        process4.setMProcessBrief(""); // 正常工序
        process4.setMiProcessAttri(2); // 外线工序属性

        ProcessSch scheduling4 = new ProcessSch();
        scheduling4.setMbHoldFlag(false);
        scheduling4.setMbNGFlag(false);

        // 设置在产工位
        Set<Long> workingPos4 = new HashSet<>();
        workingPos4.add(40006L);
        scheduling4.setMisWorkingPos(workingPos4);

        // 设置可做工位
        Set<Long> posCanDo4 = new HashSet<>();
        posCanDo4.add(40006L);
        scheduling4.setMPosCanDo(posCanDo4);

        // 设置在库件数
        CBoxSet boxesInLib4 = new CBoxSet();
        boxesInLib4.setMiCutCnt(30);
        boxesInLib4.setMiBoxCnt(3);
        scheduling4.setMBoxesInLib(boxesInLib4);

        process4.setMScheduling(scheduling4);
        hProcessSet.put(2004L, process4);

        // 保存到文件
        objectMapper.writeValue(new File(basePath + "/hProcessSet.json"), hProcessSet);

        // 生成工序依赖关系
        Map<Long, Set<Long>> hOrderProcessDependency = new HashMap<>();
        Set<Long> dependency1 = new HashSet<>();
        dependency1.add(2001L); // 工序2依赖工序1
        hOrderProcessDependency.put(2002L, dependency1);

        Set<Long> dependency2 = new HashSet<>();
        dependency2.add(2002L); // 工序3依赖工序2
        hOrderProcessDependency.put(2003L, dependency2);
        objectMapper.writeValue(new File(basePath + "/hOrderProcessDependency.json"), hOrderProcessDependency);

        // 生成可以排产的工位数据
        Set<Long> sPositionsScore = new HashSet<>();
        sPositionsScore.add(40001L);
        sPositionsScore.add(40002L);
        sPositionsScore.add(40003L);
        sPositionsScore.add(40004L);
        sPositionsScore.add(40005L);
        sPositionsScore.add(40006L);

        // 保存到文件
        objectMapper.writeValue(new File(basePath + "/sPositionsScore.json"), sPositionsScore);

        // 生成按工序查找的分数表数据
        Map<Long, List<Score>> hScoreByProcess = new HashMap<>();

        // 工序1的分数
        List<Score> scores1 = new ArrayList<>();
        Score score1_1 = new Score();
        score1_1.setPositionId(40001L);
        score1_1.setTotal(90.0);
        double[] scoreItems1 = new double[20];
        Arrays.fill(scoreItems1, 7.0);
        score1_1.setScoreItem(scoreItems1);
        scores1.add(score1_1);

        Score score1_2 = new Score();
        score1_2.setPositionId(40002L);
        score1_2.setTotal(85.0);
        double[] scoreItems2 = new double[20];
        Arrays.fill(scoreItems2, 6.5);
        score1_2.setScoreItem(scoreItems2);
        scores1.add(score1_2);

        Score score1_3 = new Score();
        score1_3.setPositionId(40003L);
        score1_3.setTotal(80.0);
        double[] scoreItems3 = new double[20];
        Arrays.fill(scoreItems3, 6.0);
        score1_3.setScoreItem(scoreItems3);
        scores1.add(score1_3);

        hScoreByProcess.put(2001L, scores1);

        // 工序2的分数 (挂起状态)
        List<Score> scores2 = new ArrayList<>();
        Score score2_1 = new Score();
        score2_1.setPositionId(40004L);
        score2_1.setTotal(80.0);
        double[] scoreItems4 = new double[20];
        Arrays.fill(scoreItems4, 5.0);
        score2_1.setScoreItem(scoreItems4);
        scores2.add(score2_1);

        hScoreByProcess.put(2002L, scores2);

        // 工序3的分数 (NG状态)
        List<Score> scores3 = new ArrayList<>();
        Score score3_1 = new Score();
        score3_1.setPositionId(40005L);
        score3_1.setTotal(70.0);
        double[] scoreItems5 = new double[20];
        Arrays.fill(scoreItems5, 4.0);
        score3_1.setScoreItem(scoreItems5);
        scores3.add(score3_1);

        hScoreByProcess.put(2003L, scores3);

        // 工序4的分数 (外线工序)
        List<Score> scores4 = new ArrayList<>();
        Score score4_1 = new Score();
        score4_1.setPositionId(40006L);
        score4_1.setTotal(75.0);
        double[] scoreItems6 = new double[20];
        Arrays.fill(scoreItems6, 4.5);
        score4_1.setScoreItem(scoreItems6);
        scores4.add(score4_1);

        hScoreByProcess.put(2004L, scores4);

        // 保存到文件
        objectMapper.writeValue(new File(basePath + "/hScoreByProcess.json"), hScoreByProcess);

        // 生成函数参数
        Map<String, Object> functionParams = new HashMap<>();
        functionParams.put("ratio", 0.15);
        objectMapper.writeValue(new File(basePath + "/testCases.json"), functionParams);

        // 更新订单中的工序分组
        processGroup1.put(1, process1);
        processGroup1.put(2, process2);
        processGroup1.put(3, process3);
        processGroup1.put(4, process4);

        // 更新orderId2Order文件，确保包含完整的工序分组信息
        objectMapper.writeValue(new File(basePath + "/orderId2Order.json"), orderId2Order);
    }

    /**
     * 清空指定目录下的所有文件
     *
     * @param directory 要清空的目录
     * @throws IOException IO异常
     */
    private static void clearDirectory(File directory) throws IOException {
        if (directory.exists() && directory.isDirectory()) {
            File[] files = directory.listFiles();
            if (files != null) {
                for (File file : files) {
                    if (file.isFile()) {
                        Files.delete(file.toPath());
                    }
                }
            }
        }
    }

    /**
     * 生成系统参数数据
     */
    private static void generateSysParamData(String basePath) throws IOException {
        Map<String, SysParam> hParamSet = new HashMap<>();

        SysParam minInLibSTDPer = new SysParam();
        minInLibSTDPer.setParamCode("MinInLibSTDPer");
        minInLibSTDPer.setParamDefaultValue(String.valueOf(100 + random.nextInt(1000))); // 100-1100的随机值
        hParamSet.put("MinInLibSTDPer", minInLibSTDPer);

        objectMapper.writeValue(new File(basePath + "/hParamSet.json"), hParamSet);
    }

    /**
     * 生成订单数据
     */
    private static Map<String, OrderDto> generateOrderData(String basePath) throws IOException {
        Map<String, OrderDto> orderId2Order = new HashMap<>();

        // 随机生成订单数量 2-5个
        int orderCount = 2 + random.nextInt(4);

        for (int i = 0; i < orderCount; i++) {
            OrderDto order = OrderDto.InitOrder();
            String orderNum = "TEST" + (5000 + i) + "" + (100000 + random.nextInt(900000));
            order.setMLocalOrderNum(orderNum);
            order.setMiTotalPlanCnt(500 + random.nextInt(1001)); // 500-1500

            // 初始化工序分组，但不预设具体的工序，因为这些将在工序集生成时确定
            Map<Integer, OrderProcess> processGroup = new TreeMap<>();
            int partCount = 1 + random.nextInt(3); // 1-3个部件
            for (int j = 0; j < partCount; j++) {
                // 在这里只初始化部件，不设置具体工序，因为工序将在后续生成
                // 工序将在 generateProcessSetData 方法中创建并添加到订单中
            }

            orderId2Order.put(orderNum, order);
        }

        objectMapper.writeValue(new File(basePath + "/orderId2Order.json"), orderId2Order);
        return orderId2Order;
    }

    /**
     * 生成工序依赖关系数据
     */
    private static Map<Long, Set<Long>> generateProcessDependencyData(String basePath, Map<Long, OrderProcess> hProcessSet) throws IOException {
        Map<Long, Set<Long>> hOrderProcessDependency = new HashMap<>();

        // 获取实际的工序ID列表
        List<Long> processIds = new ArrayList<>(hProcessSet.keySet());

        if (processIds.isEmpty()) {
            // 如果没有工序，则直接返回空的依赖关系
            objectMapper.writeValue(new File(basePath + "/hOrderProcessDependency.json"), hOrderProcessDependency);
            return hOrderProcessDependency;
        }

        // 随机生成依赖关系
        int dependencyCount = Math.min(3 + random.nextInt(8), processIds.size()); // 3-10个依赖关系，但不超过实际工序数

        // 用于跟踪已选择的工序，避免重复选择
        Set<Long> selectedProcessIds = new HashSet<>();

        for (int i = 0; i < dependencyCount; i++) {
            // 选择一个工序作为依赖目标
            Long processId;
            int attempts = 0;
            do {
                processId = processIds.get(random.nextInt(processIds.size()));
                attempts++;
                // 防止无限循环
                if (attempts > processIds.size() * 2) {
                    break;
                }
            } while (selectedProcessIds.contains(processId));

            if (attempts > processIds.size() * 2) {
                break; // 如果无法选择新的工序，跳出循环
            }

            selectedProcessIds.add(processId);
            Set<Long> dependencies = new HashSet<>();

            // 每个工序有0-3个依赖
            int depCount = random.nextInt(4);

            // 确保依赖的工序ID在工序集中，并且不产生循环依赖
            List<Long> validDependencies = new ArrayList<>();
            for (Long id : processIds) {
                // 只能依赖排在它前面的工序，避免循环依赖
                // 这里使用ID值比较来确保顺序，实际项目中可能需要更复杂的逻辑
                if (id < processId) {
                    validDependencies.add(id);
                }
            }

            if (!validDependencies.isEmpty()) {
                int actualDepCount = Math.min(depCount, validDependencies.size());
                Collections.shuffle(validDependencies);
                for (int j = 0; j < actualDepCount; j++) {
                    dependencies.add(validDependencies.get(j));
                }
            }

            if (!dependencies.isEmpty()) {
                hOrderProcessDependency.put(processId, dependencies);
            }
        }

        objectMapper.writeValue(new File(basePath + "/hOrderProcessDependency.json"), hOrderProcessDependency);
        return hOrderProcessDependency;
    }

    /**
     * 生成工序集数据
     */
    private static Map<Long, OrderProcess> generateProcessSetData(String basePath,
                                                                  Map<String, OrderDto> orderId2Order,
                                                                  Map<Long, Set<Long>> hOrderProcessDependency) throws IOException {
        Map<Long, OrderProcess> hProcessSet = new HashMap<>();

        // 获取订单列表
        List<String> orderNums = new ArrayList<>(orderId2Order.keySet());
        if (orderNums.isEmpty()) {
            // 如果没有订单，创建一个默认订单
            OrderDto defaultOrder = OrderDto.InitOrder();
            defaultOrder.setMLocalOrderNum("DEFAULT_ORDER");
            defaultOrder.setMiTotalPlanCnt(1000);
            orderId2Order.put("DEFAULT_ORDER", defaultOrder);
            orderNums.add("DEFAULT_ORDER");
        }

        // 随机生成工序数量 3-8个
        int processCount = 3 + random.nextInt(6);

        List<String> orderNumList = new ArrayList<>(orderId2Order.keySet());

        for (int i = 0; i < processCount; i++) {
            String orderNum = orderNumList.get(random.nextInt(orderNumList.size()));
            OrderDto orderDto = orderId2Order.get(orderNum);

            OrderProcess process = OrderProcess.InitOrderProcess(orderDto);
            long processId = 1000L + i * 10 + random.nextInt(10);
            process.setProcessId(processId);
            process.setOrderProcessId(processId);
            // 标准工时保留两位小数
            float processTime = 60.0f + random.nextInt(600);
            processTime = new BigDecimal(processTime).setScale(2, RoundingMode.HALF_UP).floatValue();
            process.setMfProcessTotalTime(processTime); // 60-660秒标准工时
            process.setMiFinishedCnt(random.nextInt(orderDto.getMiTotalPlanCnt()));
            process.setMiPartSeqNum(i + 1);
            process.setMPartId((long) (100 + random.nextInt(3))); // 100-102部件ID

            // 随机设置工序类型
            int processType = random.nextInt(10);
            if (processType < 7) {
                // 70%概率为正常工序
                process.setMProcessBrief("");
                process.setMiProcessAttri(0);
            } else if (processType < 8) {
                // 10%概率为外线工序
                process.setMProcessBrief("");
                process.setMiProcessAttri(2);
            } else if (processType < 9) {
                // 10%概率为中断工序
                process.setMProcessBrief("中断");
                process.setMiProcessAttri(0);
            } else {
                // 10%概率为二次打包工序
                process.setMProcessBrief("二次打包");
                process.setMiProcessAttri(0);
            }

            ProcessSch scheduling = new ProcessSch();
            scheduling.setMbHoldFlag(random.nextDouble() < 0.1); // 10%概率为挂起状态
            scheduling.setMbNGFlag(random.nextDouble() < 0.1); // 10%概率为NG状态

            // 设置在产工位
            Set<Long> workingPos = new HashSet<>();
            int workingPosCount = random.nextInt(4); // 0-3个在产工位
            for (int j = 0; j < workingPosCount; j++) {
                workingPos.add((long) (10000 + random.nextInt(90000))); // 10000-99999的工位ID
            }
            scheduling.setMisWorkingPos(workingPos);

            // 设置可做工位集合
            Set<Long> posCanDo = new HashSet<>();
            int posCount = 2 + random.nextInt(5); // 2-6个工位
            for (int j = 0; j < posCount; j++) {
                posCanDo.add((long) (10000 + random.nextInt(90000))); // 10000-99999的工位ID
            }
            scheduling.setMPosCanDo(posCanDo);

            // 设置在库件数
            CBoxSet boxesInLib = new CBoxSet();
            boxesInLib.setMiCutCnt(random.nextInt(200)); // 0-199裁片件数
            boxesInLib.setMiBoxCnt(random.nextInt(20)); // 0-19筐数
            scheduling.setMBoxesInLib(boxesInLib);

            process.setMScheduling(scheduling);
            hProcessSet.put(processId, process);

            // 更新订单中的工序分组
            if (orderDto != null && orderDto.getMOrderProcessSetGroupByPart() != null) {
                Map<Integer, OrderProcess> partProcessMap = orderDto.getMOrderProcessSetGroupByPart().get(process.getMPartId().intValue());
                if (partProcessMap == null) {
                    partProcessMap = new TreeMap<>();
                    orderDto.getMOrderProcessSetGroupByPart().put((long) process.getMPartId().intValue(), partProcessMap);
                }
                // 将工序添加到订单的工序分组中
                partProcessMap.put(process.getMiPartSeqNum(), process);
            }
        }

        // 保存到文件
        objectMapper.writeValue(new File(basePath + "/hProcessSet.json"), hProcessSet);

        return hProcessSet;
    }

    /**
     * 生成可以排产的工位数据
     */
    private static Set<Long> generatePositionScoreData(String basePath) throws IOException {
        Set<Long> sPositionsScore = new HashSet<>();

        // 随机生成工位数量 5-15个
        int positionCount = 5 + random.nextInt(11);

        // 添加测试工位ID
        for (int i = 0; i < positionCount; i++) {
            sPositionsScore.add((long) (10000 + random.nextInt(90000))); // 10000-99999的工位ID
        }

        // 保存到文件
        objectMapper.writeValue(new File(basePath + "/sPositionsScore.json"), sPositionsScore);

        return sPositionsScore;
    }

    /**
     * 生成按工序查找的分数表数据
     */
    private static void generateScoreByProcessData(String basePath, Map<Long, OrderProcess> hProcessSet,
                                                   Set<Long> sPositionsScore) throws IOException {
        Map<Long, List<Score>> hScoreByProcess = new HashMap<>();

        // 使用已生成的工序ID来创建分数数据
        List<Long> processIds = new ArrayList<>(hProcessSet.keySet());

        for (Long processId : processIds) {
            List<Score> scores = new ArrayList<>();

            // 获取部分工位ID用于这个工序
            List<Long> positionIds = new ArrayList<>(sPositionsScore);
            Collections.shuffle(positionIds); // 随机打乱

            // 每个工序对应1-5个工位分数（不超过工位总数）
            int scoreCount = Math.min(1 + random.nextInt(5), positionIds.size());
            for (int j = 0; j < scoreCount; j++) {
                Score score = new Score();
                score.setPositionId(positionIds.get(j));
                // 总分保留两位小数
                double total = random.nextDouble() * 100; // 0-100的总分
                total = new BigDecimal(total).setScale(2, RoundingMode.HALF_UP).doubleValue();
                score.setTotal(total);

                // 初始化分数项数组，包含随机分数，每项保留两位小数
                double[] scoreItems = new double[20];
                for (int k = 0; k < scoreItems.length; k++) {
                    double item = random.nextDouble() * 50; // 0-50的分数项
                    item = new BigDecimal(item).setScale(2, RoundingMode.HALF_UP).doubleValue();
                    scoreItems[k] = item;
                }
                score.setScoreItem(scoreItems);

                scores.add(score);
            }

            hScoreByProcess.put(processId, scores);
        }

        // 保存到文件
        objectMapper.writeValue(new File(basePath + "/hScoreByProcess.json"), hScoreByProcess);
    }

    /**
     * 生成函数参数
     */
    private static void generateFunctionParams(String basePath) throws IOException {
        Map<String, Object> functionParams = new HashMap<>();
        // 生成 0.01 到 1.0 之间的随机 ratio 值，保留两位小数
        double randomRatio = 0.01 + random.nextDouble() * 0.99;
        randomRatio = new BigDecimal(randomRatio).setScale(2, RoundingMode.HALF_UP).doubleValue();
        functionParams.put("ratio", randomRatio);
        objectMapper.writeValue(new File(basePath + "/testCases.json"), functionParams);
    }

    public static void main(String[] args) {
        try {
            // 确保主目录存在
            File mainDir = new File("../../test_data/calculateItem_5");
            if (!mainDir.exists()) {
                mainDir.mkdirs();
            }

            // 生成50组随机测试数据
            for (int i = 1; i <= 50; i++) {
                generateRandomTestData(i);
                System.out.println("随机测试数据集 " + i + " 已成功生成");
            }

            // 生成2个手动测试案例
            for (int i = 1; i <= 2; i++) {
                generateManualTestData(i);
                System.out.println("手动测试案例 " + i + " 已成功生成");
            }

            System.out.println("所有测试数据已成功生成并保存到../../test_data/calculateItem_5目录下");
        } catch (IOException e) {
            System.err.println("生成测试数据时发生错误: " + e.getMessage());
            e.printStackTrace();
        }
    }
}